#pragma once

#include "error.hpp"
#include <iostream>
#include <cstdlib>
#include <unistd.h>
#include <sys/epoll.h>

using namespace std;

class Epoller
{
public:
    Epoller()
    : _epfd(-1)
    {}

    ~Epoller()
    {
        if (_epfd != -1)
            close(_epfd);
    }

    void Create()
    {
        _epfd = epoll_create(1);
        if (_epfd < 0)
        {
            cout << "epoll create error" << endl;
            exit(EPOLL_CRE_ERR);
        }
        cout << "epoll create success, epfd: " << _epfd << endl;
    }

    //添加sock到epoll模型 修改epoll模型中sock关心的事件 将sock从epoll模型中删除
    void Control(int sock, uint32_t events, int action)
    {
        struct epoll_event ev;
        ev.data.fd = sock;
        ev.events = events;
        int n = 0;
        if (action == EPOLL_CTL_ADD)
            n = epoll_ctl(_epfd, action, sock, &ev);
        else if (action == EPOLL_CTL_MOD)
            n = epoll_ctl(_epfd, action, sock, &ev);
        else if (action == EPOLL_CTL_DEL)
            n = epoll_ctl(_epfd, action, sock, nullptr);
        else
            n = -1;
        if (n == -1)
        {
            cout << "epoll control error" << endl;
            exit(EPOLL_CTL_ERR);
        }
    }

    int Wait(struct epoll_event revs[], int maxevents, int timeout)
    {
        return epoll_wait(_epfd, revs, maxevents, timeout);
    }

private:
    int _epfd;
};